package de.duester.vectordrawing;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

/**
 * @author Maxim Duester
 */
public class DrawingView extends SurfaceView implements Callback {
	private Scene scene;
	private DrawingThread drawingThread;

	/**
	 * @param context
	 */
	public DrawingView(Context context) {
		super(context);
		init();
	}

	/**
	 * @param context
	 * @param attrs
	 */
	public DrawingView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		SurfaceHolder holder = getHolder();
		holder.addCallback(this);
	}

	/**
	 * @param scene
	 */
	public void setScene(Scene scene) {
		this.scene = scene;
	}

	/* (non-Javadoc)
	 * @see android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
	 */
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	}

	/* (non-Javadoc)
	 * @see android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder)
	 */
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		drawingThread = new DrawingThread(holder);
		drawingThread.setFlag(true);
		drawingThread.start();
	}

	/* (non-Javadoc)
	 * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.SurfaceHolder)
	 */
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		drawingThread.setFlag(false);
		while (retry) {
			try {
				drawingThread.join();
				retry = false;
			} catch (InterruptedException e) {
			}
		}
		drawingThread = null;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (scene.getBackgroundDrawable() != null)
			scene.getBackgroundDrawable().draw(canvas);
		else
			canvas.drawColor(scene.getBackgroundColor());
		scene.paint(canvas);
	}

	class DrawingThread extends Thread {
		private SurfaceHolder holder;
		private boolean flag = false;

		public DrawingThread(SurfaceHolder holder) {
			this.holder = holder;
		}

		public void setFlag(boolean flag) {
			this.flag = flag;
		}

		@SuppressLint("WrongCall")
		@Override
		public void run() {
			Canvas canvas;
			while (flag) {
				canvas = null;
				try {
					canvas = holder.lockCanvas();
					synchronized (holder) {
						DrawingView.this.onDraw(canvas);
					}
				} catch (Exception e) {
				} finally {
					if (canvas != null)
						holder.unlockCanvasAndPost(canvas);
				}
			}
		}
	}

}
